package com.ls.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ls.constant.SystemConstants;
import com.ls.entity.Customer;
import com.ls.entity.OrderRecord;
import com.ls.entity.Product;
import com.ls.mapper.OrderRecordMapper;
import com.ls.service.IAlipayPayService;
import com.ls.service.ICustomerService;
import com.ls.service.IOrderRecordService;
import com.ls.service.IProductService;
import com.ls.utils.ResultData;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.ls.constant.SystemConstants.*;
import static com.ls.enums.OrderRecordEnum.getOrderRecordEnum;

/**
 * <p>
 * 支付宝支付 服务实现类
 * </p>
 *
 * @author pengyu
 * @since 2024-10-12
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AlipayPayServiceImpl extends ServiceImpl<OrderRecordMapper, OrderRecord> implements IAlipayPayService {
    private final ICustomerService customerService;
    private final IProductService productService;
    private final IOrderRecordService orderRecordService;
    @Value("${ali-pay.appid}")
    private String appid;
    @Value("${ali-pay.notifyUrl}")
    private String notifyUrl;
    @Value("${ali-pay.publicKey}")
    private String publicKey;
    @Value("${ali-pay.privateKey}")
    private String privateKey;
    @Value("${ali-pay.alipayPublicKey}")
    private String alipayPublicKey;
    @Value("${ali-pay.gatewayUrl}")
    private String gatewayUrl;
    @Value("${ali-pay.charset}")
    private String charset;
    @Value("${ali-pay.signType}")
    private String signType;
    @Value("${ali-pay.format}")
    private String format;
    @Value("${pay.expire.time}")
    private Integer time;
    @Value("${pay.polling.count}")
    private Integer count;

    private AlipayConfig getAlipayConfig() {
        AlipayConfig alipayConfig = new AlipayConfig();
        //设置网关地址
        alipayConfig.setServerUrl(gatewayUrl);
        //设置应用ID
        alipayConfig.setAppId(appid);
        //设置应用私钥
        alipayConfig.setPrivateKey(privateKey);
        //设置请求格式，固定值json
        alipayConfig.setFormat(format);
        //设置字符集
        alipayConfig.setCharset(charset);
        //设置支付宝公钥
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        //设置签名类型
        alipayConfig.setSignType(signType);
        return alipayConfig;
    }
    /*
     *预支付
     */
    @Override
    public ResultData advancePay(String orderNum, BigDecimal money, Integer productType) {
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
            log.info("支付宝初始化成功:{}", alipayClient);
            // 创建API请求
            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            // 设置商户订单号
            model.setOutTradeNo(orderNum);
            // 设置订单总金额
            model.setTotalAmount(String.format("%.2f", money));

            // 设置订单标题
            model.setSubject(productType==PRODUCT_TYPE_MEMBER?"乐信通会员服务":productType==PRODUCT_TYPE_SMS?"乐信通短信套餐":"乐信通加量包");
            // 设置产品码
            model.setProductCode("QUICK_MSECURITY_PAY");
            //获取当前时间加三十分钟
            model.setTimeExpire(LocalDateTime.now().plusMinutes(time).toString());
            request.setBizModel(model);
            request.setNotifyUrl(notifyUrl);
            // 执行请求
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            if (response.isSuccess()) {
                return ResultData.successData(response.getBody());
            } else {
                throw new RuntimeException("生成支付二维码失败：" + response.getSubMsg());
            }

        } catch (Exception e) {
            log.error("支付宝支付异常:{}", e);
            return ResultData.failure(e.getMessage());
        }

    }
    /*
     *支付结果异步回调
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String getPayType(Map<String, String> params) {
        try {
            // 验证签名
            boolean verifyResult = AlipaySignature.rsaCheckV1(
                    params,
                    alipayPublicKey, charset, signType
            );
            if (verifyResult) {
                if ("TRADE_SUCCESS".equals(params.get("trade_status"))) {
                    //付款时间
                    String successTime = params.get("gmt_payment");
                    // 创建匹配的格式化器
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    LocalDateTime dbTime = LocalDateTime.parse(successTime, formatter);
                    ResultData resultData = orderRecordService.changeOrder(params.get("out_trade_no"),params.get("trade_no"),dbTime);
                    if (resultData.isSuccess()) {
                        Map<String, Object> resultMap = (Map<String, Object>) resultData.getData();
                        Boolean isOk = (Boolean) resultMap.get("isOk");
                        if (isOk){
                            Long customerId = Long.parseLong(resultMap.get("customerId").toString());
                            Long productId = Long.parseLong(resultMap.get("productId").toString());
                            Long orderRecordId=Long.parseLong(resultMap.get("orderRecordId").toString());
                            Boolean isChange=customerService.changeCustomer(customerId,productId,orderRecordId);
                            if (isChange){
                                return "success";
                            }else {
                                return "fail";
                            }
                        }
                    }
                }
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return "success";
    }

    /*
     *统一查询支付接口
     */
    @Override
    public ResultData getPayStatus(String orderNum) {
        try {
            // 初始化SDK
            AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
            // 构造请求参数以调用接口
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            AlipayTradeQueryModel model = new AlipayTradeQueryModel();

            // 设置订单支付时传入的商户订单号
            model.setOutTradeNo(orderNum);

            // 设置查询选项
            List<String> queryOptions = new ArrayList<String>();
            queryOptions.add("trade_settle_info");
            model.setQueryOptions(queryOptions);

            request.setBizModel(model);
            // 第三方代调用模式下请设置app_auth_token
            AlipayTradeQueryResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                if ("TRADE_SUCCESS".equals(response.getTradeStatus())){
                    return ResultData.successData(true);
                }else {
                    return ResultData.successData(false);
                }
            } else {
                // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
                // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
                // System.out.println(diagnosisUrl);
                return ResultData.failure("调用失败");
            }
        } catch (Exception e) {
            log.error("支付宝支付异常:{}", e);
            return ResultData.failure(e.getMessage());
        }

    }
    /*
     *统一轮询查询支付接口
     */
    @Override
    public String getTaskPayStatus(String orderNum) {
        try {
            // 初始化SDK
            AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
            // 构造请求参数以调用接口
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            AlipayTradeQueryModel model = new AlipayTradeQueryModel();

            // 设置订单支付时传入的商户订单号
            model.setOutTradeNo(orderNum);

            // 设置查询选项
            List<String> queryOptions = new ArrayList<String>();
            queryOptions.add("trade_settle_info");
            model.setQueryOptions(queryOptions);
            request.setBizModel(model);
            // 第三方代调用模式下请设置app_auth_token
            AlipayTradeQueryResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                if ("TRADE_SUCCESS".equals(response.getTradeStatus())){
                    return response.getTradeNo();
                }else {
                    return "false";
                }
            } else {
                return "false";
            }
        } catch (Exception e) {
            log.error("支付宝支付异常:{}", e);
            return "false";
        }

    }

    /*
     *关闭订单
     */
    @Override
    public ResultData closeOrder(String orderNum) {
        try {

            // 初始化SDK
            AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());

            // 构造请求参数以调用接口
            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
            AlipayTradeCloseModel model = new AlipayTradeCloseModel();
            // 设置订单支付时传入的商户订单号
            model.setOutTradeNo(orderNum);
            request.setBizModel(model);

            AlipayTradeCloseResponse response = alipayClient.execute(request);
            log.info("关闭订单{}",JSON.toJSONString(response));
//            if (response.isSuccess()) {
//
//            }
            orderRecordService.orderExpire(orderNum);
            return ResultData.success();
        } catch (Exception e) {
            log.error("支付宝关闭订单异常:{}", e);
        }
        return ResultData.failure("支付宝关闭订单异常");
    }
    /*
     *退款
     */
    @Override
    public ResultData refundApply(String orderNum,BigDecimal money) {
        try {

            // 初始化SDK
            AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());

            // 构造请求参数以调用接口
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            AlipayTradeRefundModel model = new AlipayTradeRefundModel();
            // 设置订单支付时传入的商户订单号
            model.setOutTradeNo(orderNum);
            model.setRefundAmount(String.valueOf(money));
            request.setBizModel(model);

            AlipayTradeRefundResponse response = alipayClient.execute(request);
            log.info("修改支付订单状态{}",response.getBody());

            if (response.isSuccess()) {
                boolean refundSuccess = false;
                for (int i = 0; i < count; i++) {
                    Boolean queryResult = this.refundQuery(orderNum);
                    if (queryResult) {
                        refundSuccess = true;
                        break;
                    }
                    Thread.sleep(2000);
                }
                if (refundSuccess){
                    //修改支付订单状态
                    boolean updateResult = update(new UpdateWrapper<OrderRecord>()
                            .eq("order_num", orderNum)
                            .set("order_status", PAY_STATUS_REFUND_SUCCESS));
                    if (!updateResult) {
                        log.error("订单状态更新失败，订单号：{}", orderNum);
                        return ResultData.failure("订单状态更新失败");
                    }
                    log.info("订单已成功关闭并更新状态，订单号：{}", orderNum);
                    //根据orderNum查询订单id
                    OrderRecord orderRecord = orderRecordService.getOrderRecordByOrderNum(orderNum);
                    if (orderRecord.getOrderRecordId()!=null){
                        ResultData resultData = orderRecordService.refund(orderRecord.getOrderRecordId(), money);
                        if (resultData.getCode()==200){
                            return ResultData.successMsg("订单已成功关闭");
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("支付宝关闭订单异常:{}", e);
        }
        return ResultData.failure("订单状态更新失败");
    }
    /*
     *退款查询
     */
    @Override
    public Boolean refundQuery(String orderNum) {
        try {

            AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());

            // 构造请求参数以调用接口
            AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
            AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();

            // 设置商户订单号
            model.setOutTradeNo(orderNum);
            model.setOutRequestNo(orderNum);

            // 设置查询选项
            List<String> queryOptions = new ArrayList<String>();
            queryOptions.add("refund_detail_item_list");
            model.setQueryOptions(queryOptions);

            request.setBizModel(model);

            AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request);
            log.info("支付宝关闭订单{}",response.isSuccess());
            if (response.isSuccess()) {
                return true;
            }
        } catch (Exception e) {
            log.error("支付宝关闭订单异常:{}", e);
        }
        return false;
    }
}
